package lemon.mvc.mvc.internal;

//package com.bj58.wf.mvc.internal;
//
//import java.io.File;
//import java.io.IOException;
//import java.io.InputStream;
//import java.lang.reflect.Modifier;
//import java.util.Map;
//import java.util.PropertyResourceBundle;
//import java.util.Set;
//import java.util.regex.Pattern;
//
//import com.bj58.wf.mvc.WFController;
//import com.bj58.wf.mvc.WFException;
//import com.bj58.wf.mvc.convention.EmptyModule;
//import com.bj58.wf.mvc.convention.GroupConvention;
//import com.bj58.wf.mvc.convention.GroupConventionAnnotation;
//import com.bj58.wf.mvc.convention.ProjectConvention;
//import com.bj58.wf.mvc.utils.ClassUtils;
//import com.google.common.collect.ImmutableMap;
//import com.google.common.collect.ImmutableSet;
//import com.google.common.collect.Maps;
//import com.google.inject.Binder;
//import com.google.inject.Module;
//
//@GroupConventionAnnotation
//public class DefaultGroupConvention implements GroupConvention {
//
//    private static final String GROUP_CONFIG_FOLDER = "groupConfigFolder";
//    public static final String GROUP_LOG_FOLDER = "groupLogFolder";
//
//    private static final String PROJECT_ID = "projectId";
//
//    public static final String PACKAGES_PREFIX = "groupPackagesPrefix";
//    
//    private final File folder;
//    private final GroupConfig groupConfig;
//    private final ProjectConfig projectConfig;
//    
//    
//    public DefaultGroupConvention(GroupConventionAnnotation groupConventionAnnotation, File folder) {
//
//        this.folder = folder;
//
//        ProjectConvention projectConvention = parseProjectConvention(groupConventionAnnotation);
//        Map<String, String> configInfoMap = parseGroupConventionPath(groupConventionAnnotation, projectConvention);
//
//        groupConfig = parseGroupConfig(groupConventionAnnotation, configInfoMap);
//
//        projectConfig = parseProjectConfig(projectConvention, groupConventionAnnotation);
//
//    }
//
//
//    @Override
//    public GroupConfig group() {
//        return groupConfig;
//    }
//
//    @Override
//    public ProjectConfig currentProject() {
//        return projectConfig;
//    }
//
//    /**
//     * 解析Group规范
//     * @param groupConventionAnnotation 组织级注解
//     * @return Group规范
//     */
//    private GroupConfig parseGroupConfig(GroupConventionAnnotation groupConventionAnnotation
//            , Map<String, String> configInfoMap) {
//
//        String configPath = configInfoMap.get(GROUP_CONFIG_FOLDER);
//        String logPath = configInfoMap.get(GROUP_LOG_FOLDER);
//
//        Module module =  EmptyModule.class.isAssignableFrom(groupConventionAnnotation.groupModule())
//                ? EmptyModule.instance
//                : newInstanceByClass(groupConventionAnnotation.groupModule(), "");
//
//        return new DefaultGroupConfig(getDir(configPath), getDir(logPath), module);
//
//    }
//
//    private ProjectConfig parseProjectConfig(ProjectConvention projectConvention,
//                                             GroupConventionAnnotation groupConventionAnnotation) {
//
////        Set<Class<? extends WFController>> controllersClasses = parseControllers(groupConventionAnnotation);
//
//        return new DefaultProjectConfig(projectConvention.id(), projectConvention);
//
//    }
//
//
//    private <T> T newInstanceByClass(Class<T> clazz, String message) {
//        try {
//            return clazz.newInstance();
//        }  catch (Exception e) {
//            throw WFException.raise(message, e);
//        }
//    }
//
//    /**
//     * 解析项目规范
//     * @param groupConventionAnnotation 组织级注解
//     * @return 项目规范信息
//     */
//    ProjectConvention parseProjectConvention(GroupConventionAnnotation groupConventionAnnotation) {
//
//        String className = groupConventionAnnotation.projectConventionClass();
//
//        Class<?> clazz;
//        try {
//            clazz = Thread.currentThread().getContextClassLoader().loadClass(className);
//        } catch (ClassNotFoundException e) {
//            return new ProjectConvention() {
//                @Override
//                public String id() {
//                	
//                	//名称空间
//					String namespace = "";
//					
//					try {
//						
//						ClassLoader cl = Thread.currentThread().getContextClassLoader();
//						InputStream inputStream = cl.getResourceAsStream("META-INF/namespace.properties");
//						PropertyResourceBundle pp = new PropertyResourceBundle(inputStream);
//						
//						namespace = pp.containsKey("namespace") ? pp.getString("namespace") : "";
//						if(namespace == null || "".equals(namespace.trim()))
//							throw new Exception("Does not specify a value for the namespace");
//					} catch (IOException e) {
//						// TODO Auto-generated catch block
//						e.printStackTrace();
//					} catch (Exception e) {
//						// TODO Auto-generated catch block
//						e.printStackTrace();
//					}
//                	
//                    return namespace;
//                }
//
//                @Override
//                public void configure(Binder binder) {
//                }
//            };
//        }
//
//        ProjectConvention projectConvention = null;
//        if(ProjectConvention.class.isAssignableFrom(clazz)){
//            //TODO:需要描述，为何抛错，这个类必须继承ProjectConvention并实现,并且构造函数必须无参。
//            projectConvention = ProjectConvention.class.cast(newInstanceByClass(clazz, ""));
//        }
//
//        if (projectConvention != null)
//            return projectConvention;
//
//        throw WFException
//                .raise(String.format("Class %s not implement ProjectConvention!", className));
//
//    }
//
//    private Map<String, String> parseGroupConventionPath(GroupConventionAnnotation groupConventionAnnotation
//            , ProjectConvention projectConvention) {
//
//        Map<String, String> paths = ImmutableMap.<String, String>builder()
//                .put(PACKAGES_PREFIX, groupConventionAnnotation.groupPackagesPrefix())
//                .put(PROJECT_ID, projectConvention.id())
//                .put(GROUP_CONFIG_FOLDER, groupConventionAnnotation.groupConfigFolder())
//                .put(GROUP_LOG_FOLDER, groupConventionAnnotation.groupLogFolder())
//                .build();
//
//        return matchPath(paths);
//
//    }
//
//    static Map<String, String> matchPath(Map<String, String> paths) {
//        Map<String, String> values = Maps.newHashMap();
//        Map<String, String> templates = Maps.newHashMap();
//        Map<String, String> result = Maps.newHashMap();
//
//        classify(paths, values, templates);
//
//        while (values.size() > 0) {
//            values = migrate(values, templates, result);
//        }
//
//        if (templates.size() > 0)
//            throw WFException.newBuilder("GroupConventionAnnotation contains nested expression")
//                    .addContextVariables(templates)
//                    .build();
//
//        return result;
//
//    }
//
//    /**
//     * 将定值数据保存到结果数据集合，并将模板数据用定值数据进行替换，并返回替换后的定值
//     * @param values 定值数据集合
//     * @param templates 模板数据集合
//     * @param result 结果数据集合
//     * @return 由模板替换后生成的定值数据
//     */
//    static Map<String, String> migrate(Map<String, String> values, Map<String, String> templates, Map<String, String> result) {
//        result.putAll(values);
//
//
//        for (Map.Entry<String, String> templateItem : templates.entrySet()) {
//            String v = templateItem.getValue();
//            for (Map.Entry<String, String> valueItem : values.entrySet()) {
//                String exp = '{' + valueItem.getKey() + '}';
//
//                if (v.contains(exp))
//                    v = v.replace(exp, valueItem.getValue());
//
//            }
//
//            if (!v.equals(templateItem.getValue()))
//                templateItem.setValue(v);
//        }
//
//        Map<String, String> newValues = Maps.newHashMap();
//        Map<String, String> newTemplates = Maps.newHashMap();
//        classify(templates, newValues, newTemplates);
//
//        templates.clear();
//        templates.putAll(newTemplates);
//
//
//        return newValues;
//
//    }
//
//
//    /**
//     * 分类数据，若路径中存在"{"，刚归类到模板数据，否则归类到定值数据
//     * @param paths 路径数据集合
//     * @param values 定值数据集合
//     * @param templates 模板数据集合
//     */
//    static void classify(Map<String, String> paths, Map<String, String> values, Map<String, String> templates) {
//        for (Map.Entry<String, String> entry : paths.entrySet()) {
//            if (entry.getValue().contains("{"))
//                templates.put(entry.getKey(), entry.getValue());
//            else
//                values.put(entry.getKey(), entry.getValue());
//
//        }
//    }
//
//    File getDir(String path) {
//
//        boolean isSub = path.charAt(0) == '.';
//
//
//
//        File dir = isSub ? new File(folder, path) : new File(path);
//
//        if (dir.isDirectory())
//            return dir;
//
//        if (dir.exists())
//            throw WFException.raise(String.format("File %s has exist, but not directory.", path));
//
//        if (!dir.mkdirs())
//            throw WFException.raise(String.format("Failed to getLogger directory %s.", path));
//
//        return dir;
//    }
//
//    @SuppressWarnings("unchecked")
//    Set<Class<? extends WFController>> parseControllers(GroupConventionAnnotation groupConventionAnnotation) {
//
//        Set<Class<?>> classSet = ClassUtils.getClasses(groupConventionAnnotation.groupPackagesPrefix());
//
//        Pattern controllerPattern = Pattern.compile(groupConventionAnnotation.controllerPattern());
//
//
//        ImmutableSet.Builder<Class<? extends WFController>> builder = ImmutableSet.builder();
//
//        for (Class<?> clazz : classSet)
//            if (applyWFController(clazz, controllerPattern))
//                builder
//                    .add((Class<? extends WFController>) clazz)
//                    .build();
//
//        return builder.build();
//    }
//
//    boolean applyWFController(Class<?> clazz, Pattern controllerPattern) {
//
//        return WFController.class.isAssignableFrom(clazz)
//                && controllerPattern.matcher(clazz.getName()).matches()
//                && !Modifier.isInterface(clazz.getModifiers())
//                && !Modifier.isAbstract(clazz.getModifiers())
//                && Modifier.isPublic(clazz.getModifiers());
//    }
//
//
//    private class DefaultGroupConfig implements GroupConfig {
//
//        private final File configFolder;
//        private final File logFolder;
//        private final Module module;
//
//        private DefaultGroupConfig(File configFolder, File logFolder, Module module) {
//            this.configFolder = configFolder;
//            this.logFolder = logFolder;
//            this.module = module;
//        }
//
//        @Override
//        public File configFolder() {
//            return configFolder;
//        }
//
//        @Override
//        public File logFolder() {
//            return logFolder;
//        }
//
//        @Override
//        public Module module() {
//            return module;
//        }
//    }
//
//    private class DefaultProjectConfig implements ProjectConfig {
//
//        private final String id;
////        private final Set<Class<? extends WFController>> controllerClasses;
//        private final Module module;
////        private final File configFolder;
////        private final File logFolder;
////        private final File viewFolder;
////        private final File staticResourcesFolder;
//
//        private DefaultProjectConfig(String id, Module module) {
//            this.id = id;
////            this.controllerClasses = controllerClasses;
//            this.module = module;
//        }
//
//        @Override
//        public String id() {
//            return id;
//        }
//
////        @Override
////        public Set<Class<? extends WFController>> controllerClasses() {
////            return controllerClasses;
////        }
//
//        @Override
//        public Module module() {
//            return module;
//        }
//    }
//
//
//
//}